# pragma once

#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <vector>
#include <sstream>
#include <cstring>
# include <fstream>
# include <filesystem>
# include <cstdio>
# include <csignal>
# include <regex>
# include <termios.h>
# include <iomanip>

volatile sig_atomic_t running = true;

void signalHandler(int signum) {
    running = false;
    std::cout << "\n收到退出信号，正在清理资源..." << std::endl;
}

double getCurrentTimeAsDouble()
{
    // 获取当前时间点（以纳秒为单位）
    auto now = std::chrono::high_resolution_clock::now();
    // 转换为自纪元（epoch）以来的总时间（以秒为单位）
    auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(now.time_since_epoch());
    return duration.count();  // 返回时间戳（double类型）
}

// 二进制数据转十六进制字符串
std::string binaryToHex(const char* data, size_t length) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (size_t i = 0; i < length; ++i) {
        ss << std::setw(2) << static_cast<unsigned int>(static_cast<unsigned char>(data[i]));
    }
    return ss.str();
}

// 十六进制字符串转二进制数据
bool hexToBinary(const std::string& hexStr, std::vector<unsigned char>& binaryData) {
    if (hexStr.length() % 2 != 0) {
        return false;  // 十六进制长度必须为偶数
    }
    
    binaryData.reserve(hexStr.length() / 2);
    for (size_t i = 0; i < hexStr.length(); i += 2) {
        std::string byteStr = hexStr.substr(i, 2);
        try {
            unsigned char byte = static_cast<unsigned char>(std::stoul(byteStr, nullptr, 16));
            binaryData.push_back(byte);
        } catch (...) {
            return false;  // 无效的十六进制字符
        }
    }
    return true;
}

// 解析十六进制日志行
bool parseLogLine(const std::string& line, double& timestamp, std::vector<unsigned char>& binaryData) {
    // 匹配格式：[时间戳]: 十六进制字符串
    std::regex pattern(R"(\[(\d+\.\d+)\]:\s*([0-9a-fA-F]+))");
    std::smatch match;
    
    if (std::regex_match(line, match, pattern) && match.size() == 3) {
        try {
            timestamp = std::stod(match[1]);
            std::string hexData = match[2];
            return hexToBinary(hexData, binaryData);  // 转二进制
        } catch (...) {
            return false;
        }
    }
    return false;
}

std::string getErrorString(int errorCode) {
    switch(errorCode) {
        case 0: return "成功";
        case -1: return "无法打开串口设备";
        case -2: return "无法配置串口";
        case -3: return "无法设置波特率";
        default: return "未知错误 (代码: " + std::to_string(errorCode) + ")";
    }
}

bool checkEnterKey() {
    struct termios oldt, newt;
    int ch;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    return (ch == '\n' || ch == EOF);
}

// 存储socat进程ID和对应的虚拟串口对
struct SocatProcess {
    pid_t pid;
    std::string vtx;
    std::string vrx;
};

// 全局存储所有创建的socat进程
std::vector<SocatProcess> socatProcesses;

// 辅助函数：检查文件路径是否有效
bool isValidPath(const std::string& path) {
    if (path.empty()) return false;
    
    // 检查路径是否包含非法字符（简单检查）
    if (path.find("..") != std::string::npos) return false;
    
    return true;
}

pid_t startSocat(const std::string& vtx, const std::string& vrx) {
    // 1. 验证输入参数
    if (!isValidPath(vtx) || !isValidPath(vrx)) {
        std::cerr << "错误：无效的设备路径 - vtx: '" << vtx << "', vrx: '" << vrx << "'" << std::endl;
        return -1;
    }

    // 2. 创建子进程
    pid_t pid = fork();
    
    if (pid < 0) {
        // fork失败
        std::cerr << "创建socat进程失败: " << strerror(errno) << std::endl;
        return -1;
    } else if (pid == 0) {
        // 子进程：执行socat命令
        // 构建参数数组，确保每个参数都是独立的
        std::string vtx_arg = "pty,raw,echo=0,link=" + vtx;
        std::string vrx_arg = "pty,raw,echo=0,link=" + vrx;
        
        const char* args[] = {
            "socat",
            "-d",
            "-d",
            vtx_arg.c_str(),
            vrx_arg.c_str(),
            nullptr  // 参数列表必须以nullptr结束
        };
        
        // 打印调试信息（子进程中）
        std::cerr << "执行socat命令: ";
        for (int i = 0; args[i] != nullptr; ++i) {
            std::cerr << args[i] << " ";
        }
        std::cerr << std::endl;
        
        // 执行socat
        execvp("socat", const_cast<char* const*>(args));
        
        // 如果execvp返回，说明执行失败
        std::cerr << "执行socat命令失败: " << strerror(errno) << std::endl;
        exit(EXIT_FAILURE);
    } else {
        // 父进程：记录PID并设置权限
        std::cout << "创建虚拟串口对: " << vtx << " (发送端) 和 " << vrx << " (接收端)" << std::endl;
        
        // 等待设备文件创建（延长等待时间，确保设备已创建）
        std::this_thread::sleep_for(std::chrono::seconds(2));
        
        // 设置权限
        std::string chmodCmd = "chmod 777 " + vtx + " " + vrx;
        int chmodResult = system(chmodCmd.c_str());
        if (chmodResult != 0) {
            std::cerr << "警告：设置权限失败，可能导致无法访问设备" << std::endl;
        }
        
        // 记录进程信息
        socatProcesses.push_back({pid, vtx, vrx});
        
        return pid;
    }
}

void stopSocat(const std::string& vtx, const std::string& vrx) {
    // 查找对应的socat进程
    for (auto it = socatProcesses.begin(); it != socatProcesses.end(); ) {
        if (it->vtx == vtx && it->vrx == vrx) {
            // 发送终止信号
            if (kill(it->pid, SIGTERM) != 0) {
                std::cerr << "杀死进程失败: " << strerror(errno) << std::endl;
            } else {
                // 等待进程结束
                int status;
                waitpid(it->pid, &status, 0);
                std::cout << "socat进程 " << it->pid << " 已终止" << std::endl;
            }
            
            // 删除链接文件
            unlink(it->vtx.c_str());
            unlink(it->vrx.c_str());
            
            // 从列表中移除
            it = socatProcesses.erase(it);
            std::cout << "已清理虚拟串口资源: " << vtx << " 和 " << vrx << std::endl;
        } else {
            ++it;
        }
    }
}

// 停止所有由本进程创建的socat
void stopAllSocats() {
    for (auto& proc : socatProcesses) {
        kill(proc.pid, SIGTERM);
        waitpid(proc.pid, nullptr, 0);
        unlink(proc.vtx.c_str());
        unlink(proc.vrx.c_str());
        std::cout << "已清理虚拟串口资源: " << proc.vtx << " 和 " << proc.vrx << std::endl;
    }
    socatProcesses.clear();
}